#include <s32strm.h>

#include "PinQModel.h"
#include "PinQTask.h"
#include "PinQCategory.h"
#include "PinQ.hrh"

CPinQModel* CPinQModel::NewL()
	{
	CPinQModel* self = new (ELeave) CPinQModel();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

CPinQModel::CPinQModel()
	{
	}

void CPinQModel::ConstructL()
	{
	}

CPinQModel::~CPinQModel()
	{
	iPinQTasks.ResetAndDestroy();
	iPinQTasks.Close();
	iPinQCategories.Close();

	delete iDeletedTask;
	}

CPinQTask& CPinQModel::Task(TUid aPinQTaskId) const
	{
	const TInt index = FindTaskIndexFromPinQUid(aPinQTaskId);
	ASSERT(index> KErrNotFound);
	return *(iPinQTasks[index]);
	}
//addnew task if it is needed
TUid CPinQModel::UpdatePrefL(TUid aUid)
	{
	if (aUid==NewTaskUid())
		{
		CPinQTask* task=CPinQTask::NewL(iTempPref);
		iTempPref.Reset();
		aUid=NewUniqueUid();
		task->SetUid(aUid);
		iPinQTasks.AppendL(task);
		}

	iDirty = ETrue;
	return aUid;
	}

void CPinQModel::RemoveTask(TInt aIndex, TBackup aBackup)
	{
	ASSERT(aIndex> KErrNotFound);
	if (iDeletedTask)
		{
		delete iDeletedTask;
		iDeletedTask = NULL;
		}
	if (aBackup==EBackup)
		iDeletedTask = &Task(aIndex);
	iPinQTasks.Remove(aIndex);
	iDirty = ETrue;
	}

void CPinQModel::RemoveTask(TUid aUid, TBackup aBackup)
	{
	const TInt index = FindTaskIndexFromPinQUid(aUid);
	RemoveTask(index, aBackup);
	}

CPinQTask& CPinQModel::RecoverDeletedTaskL()
	{
	ASSERT(iDeletedTask);
	CPinQTask& ret=*iDeletedTask;
	iPinQTasks.AppendL(iDeletedTask);
	iDeletedTask = NULL;
	iDirty = ETrue;
	return ret;
	}

TInt CPinQModel::FindTaskIndexFromPinQUid(const TUid& aUid) const
	{
	const TInt count = iPinQTasks.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQTasks[index]->Uid() == aUid)
			{
			return index;
			}
		}
	return KErrNotFound;
	}

CPinQTask* CPinQModel::RunningTask() const //might be shoud be cashed...
	{
	const TInt count = iPinQTasks.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQTasks[index]->State()!= CPinQTask::EStopped)
			return iPinQTasks[index];
		}
	return NULL;
	}

void CPinQModel::StoreL(RWriteStream& aStream) const
	{

	const TInt count = iPinQTasks.Count();
	aStream.WriteInt32L(count);

	for (TInt index = 0; index < count; index++)
		iPinQTasks[index]->ExternalizeL(aStream);

	const TInt categoryCount = iPinQCategories.Count();
	aStream.WriteInt32L(categoryCount);

	for (TInt index = 0; index < categoryCount; index++)
		{
		iPinQCategories[index].ExternalizeL(aStream);
		}

	const_cast<CPinQModel*>(this)->iDirty = EFalse;
	}

void CPinQModel::RestoreL(RReadStream& aStream)
	{
	TInt count = aStream.ReadInt32L();
	while (count--)
		{
		CPinQTask* task = CPinQTask::NewLC();
		task->InternalizeL(aStream);
		iPinQTasks.AppendL(task);
		CleanupStack::Pop(task);
		}

	count = aStream.ReadInt32L();
	if (count > 0)
		{
		while (count--)
			{
			TPinQCategory category;
			category.InternalizeL(aStream);
			AddCategory(category);
			}
		}

	}

void CPinQModel::AddCategory(const TQikCategoryName& aCategoryName,
		TInt& aHandle)
	{
	TPinQCategory category;
	category.SetCategoryHandle(aHandle);
	category.SetCategoryName(aCategoryName);
	iPinQCategories.Append(category);
	iDirty = ETrue;
	}

void CPinQModel::RenameCategory(const TInt aHandle, const TDesC& aNewName)
	{
	const TInt count = iPinQCategories.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQCategories[index].CategoryHandle() == aHandle)
			{
			iPinQCategories[index].SetCategoryName(aNewName);
			iDirty = ETrue;
			break;
			}
		}
	}

void CPinQModel::RemoveCategory(const TInt aHandle)
	{
	const TInt count = iPinQCategories.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQCategories[index].CategoryHandle() == aHandle)
			{
			iPinQCategories.Remove(index);
			iDirty = ETrue;
			break;
			}
		}
	CategoryRemoved(aHandle);
	}

void CPinQModel::CategoryRemoved(TInt aHandle)
	{
	const TInt itemCount = TaskCount();
	for (TInt index = 0; index < itemCount; index++)
		{
		CPinQTask& item = Task(index);
		if (item.Pref().Category() == aHandle)
			{
			item.Pref().SetCategory(EPinQCategoryUnfiled);
			}
		}
	if (iDeletedTask && (iDeletedTask->Pref().Category() == aHandle))
		{
		iDeletedTask->Pref().SetCategory(EPinQCategoryUnfiled);
		}
	}

TBool CPinQModel::CategoryExists(TInt aHandle)
	{
	// Always return ETrue for default categories
	if (aHandle == EPinQCategoryUnfiled)
		{
		return ETrue;
		}

	const TInt count = iPinQCategories.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQCategories[index].CategoryHandle() == aHandle)
			{
			return ETrue;
			}
		}
	return EFalse;
	}

TUid CPinQModel::NewUniqueUid()
	{
	TUid uid;
	uid.iUid = 1;

	const TInt count = iPinQTasks.Count();
	for (TInt index = 0; index < count; index++)
		{
		if (iPinQTasks[index]->Uid().iUid > uid.iUid)
			{
			uid.iUid = iPinQTasks[index]->Uid().iUid;
			}
		}
	if (iDeletedTask && iDeletedTask->Uid().iUid > uid.iUid)
		{
		uid.iUid = iDeletedTask->Uid().iUid;
		}
	uid.iUid++;
	return uid;
	}
// vim: ts=2:sw=2
